package service

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"gochat/common"
	"gochat/domain/request"
	"gochat/domain/response"
	"gochat/domain/response/result"
	"gochat/models"
	"gochat/utils/rabbitmq"
	"log"
	"net/http"
	"strconv"
	"time"
)

type MessageImpl struct {
}

func (msg MessageImpl) Message(c *gin.Context, uid string) {
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		result.Fail(c, http.StatusInternalServerError, "连接失败")
		return
	}
	db := common.DB
	//	消费消息
	consumer := rabbitmq.NewConsumer(common.RabbitPools)
	go func() {
		for {
			var routerKey []string
			var userGourp []models.UserGroup
			routerKey = append(routerKey, "private."+uid)
			//查询群聊并绑定routeKey todo动态绑定rouerkey
			db.Find(&userGourp, "user_id = ?", uid)
			for _, v := range userGourp {
				routerKey = append(routerKey, "group."+strconv.Itoa(int(v.GroupId)))
			}
			flog := 0
			err := consumer.
				Subscribe("message.group", rabbitmq.TopicExchange, routerKey, "queuename."+uid, func(msg string) {
					var data request.MessagePayload
					// 处理消息
					fmt.Println("收到消息:", msg)
					err2 := json.Unmarshal([]byte(msg), &data)
					if err2 != nil {
						log.Println("解析错误:", err2)
					} else {
						var user models.UserBasic
						err2 := db.First(&user, "id = ?", data.From).Select("id", "nick_name", "header").Error
						if err2 != nil {
							log.Println("查询用户信息失败:", err2)
							return
						}
						if data.Type == "0" {

							var privateMessageResultList response.PrivateMessageResultList
							privateMessageResultList.Message = data.Message
							privateMessageResultList.From = data.To
							privateMessageResultList.Id = data.To
							privateMessageResultList.Type = 0
							privateMessageResultList.CreateTime = time.Now()
							privateMessageResultList.NickName = user.NickName
							privateMessageResultList.Header = user.Header
							result.WsOk(websocket.TextMessage, conn, privateMessageResultList)
						} else {
							//如果是自己则不返回
							if data.From != uid {
								var groupMessageResultList response.GroupMessageResultList
								groupMessageResultList.UserInfo = struct {
									Id       uint   `json:"uid"`
									NickName string `json:"nickName"`
									Header   string `json:"header"`
								}(struct {
									Id       uint
									NickName string
									Header   string
								}{Id: user.ID, NickName: user.NickName, Header: user.Header})
								var groupModel models.GroupModel
								tx := db.First(&groupModel, "id = ?", data.GroupId).Select("group_name", "group_header")
								if tx.Error != nil {
									log.Println("查询群聊信息失败:", tx.Error)
									return
								}
								groupMessageResultList.Message = data.Message
								groupMessageResultList.CreateTime = data.CreateTime
								groupMessageResultList.GroupName = data.Type
								groupMessageResultList.GroupId = data.GroupId
								groupMessageResultList.Type = "1"
								groupMessageResultList.GroupHandler = groupModel.GroupHeader
								groupMessageResultList.GroupName = groupModel.GroupName
								result.WsOk(websocket.TextMessage, conn, groupMessageResultList)
							}

						}
					}
				})
			if err != nil {
				log.Println("RabbitMQ 订阅失败:", err)
				result.WsFail(websocket.TextMessage, conn, 2001, "连接失败,重试中...")
			}

			// 订阅结束（一般是断开导致），等待一会儿后重连
			log.Println("消费者断开，5秒后尝试重连...")
			time.Sleep(5 * time.Second)
			flog++
			if flog > 5 {
				result.WsFail(websocket.TextMessage, conn, 2001, "连接失败")
				return
			}
		}
	}()
	var payload request.MessagePayload

	for {
		err := conn.ReadJSON(&payload)
		if err != nil {
			log.Println("读取消息失败:", err)
			result.WsFail(1, conn, 2001, "读取消息失败")
			break
		}
		payload.From = uid
		payload.CreateTime = time.Now()
		if err := PermissionVerification(payload); err != nil {
			result.WsFail(websocket.TextMessage, conn, 2003, err.Error())
			continue
		}
		//	if 1群聊 or 0私聊
		data, err := json.Marshal(payload)
		if err != nil {
			log.Println("json序列化失败:", err)
			result.WsFail(websocket.TextMessage, conn, 2002, "服务器错误")
		}
		producer := rabbitmq.NewProducer(common.RabbitPools)
		if payload.Type == "0" {
			err := producer.Push("message.group", rabbitmq.TopicExchange, "private."+payload.To, string(data))
			if err != nil {
				log.Println("发送消息失败:", err)
				result.WsFail(websocket.TextMessage, conn, 2002, "发送消息失败")
				continue
			}
		} else {
			//	群聊
			err := producer.Push("message.group", rabbitmq.TopicExchange, "group."+payload.GroupId, string(data))
			if err != nil {
				log.Println("发送消息失败:", err)
				result.WsFail(websocket.TextMessage, conn, 2002, "发送消息失败")
				continue
			}
		}

	}
}

/*
*
判断用户是否有权限发送消息
是否为好友,是否在群组中
*/
func PermissionVerification(payload request.MessagePayload) error {
	db := common.DB
	if payload.Type == "0" {
		var user models.UserFriends
		if db.First(&user, "user_id = ? and friend_id = ?", payload.From, payload.To).RowsAffected < 1 {
			return errors.New("对方还不是你的好友")
		}
		if user.Status == 2 {
			return errors.New("对方已将你拉黑")
		}
		if user.Status == 3 {
			return errors.New("对方不是你的好友")
		}

	} else {
		if db.First(&models.UserGroup{}, "user_id = ? and group_id = ?", payload.From, payload.GroupId).RowsAffected < 1 {
			return errors.New("请先加入群聊")
		}
	}

	return nil
}

// 定义WebSocket升级器
var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true // 允许所有来源的连接
	},
}
